// file: include/os/schedule.h
// autor:jiangxinpeng
// time:2021.1.17
// copyright:(C) 2020-2050 by jiangxinpeng,All right are reserved.

#ifndef _OS_SCHEDULE_H
#define _OS_SCHEDULE_H

#include <arch/cpu.h>
#include <os/spinlock.h>
#include <os/task.h>
#include <lib/type.h>
#include <lib/list.h>

#define TASK_NUM_HIGH 32

typedef struct sched_queue
{
    spinlock_t lock;
    list_t list;
    uint32_t len;      // queue task len
    uint32_t priority; // queue priority
} sched_queue_t;

typedef struct sched_unit
{
    spinlock_t lock;
    cpuid_t cpuid; // schedule unit cpuid
    flags_t flags;
    uint32_t tasknum;                                   // schedule unit task count
    uint32_t dynamic_proiority;                         // schedule unit dynamic proirity
    task_t *idle;                                       // current schedule unit idle task
    task_t *cur;                                        // current schedule unit run task
    sched_queue_t priority_queue[TASK_PRIOR_LEVEL_MAX]; // priority queue
} sched_unit_t;

typedef struct
{
    spinlock_t lock;
    uint32_t cpunum;                            // cpu num
    uint32_t tasknum;                           // task num
    sched_unit_t sched_unit_table[CPU_NUM_MAX]; // schedunit table
} schedule_t;

extern schedule_t *schedule;

extern volatile uint8_t sched_flags;

void ScheduleInit();
void ScheduleUnitInit(sched_unit_t *unit, cpuid_t cpuid, int flags);
sched_unit_t *SchedGetCurUnit();
int SchedQueueHadTask(sched_unit_t *su, task_t *task);
int SchedQueueAddTaskTail(sched_unit_t *su, task_t *task);
int SchedQueueAddHead(sched_unit_t *su, task_t *task);
void SchedSetNextTask(sched_unit_t *su, task_t *next);
task_t *SchedGetNextTask(sched_unit_t *su);
task_t *SchedQueueFetchFirst(sched_unit_t *su);
void Schedule();
uint8_t SchedCalcNewPriority(task_t *task, char adjustment);
sched_unit_t *SchedGetFreeUnit();
sched_unit_t *SchedFindByCpu(cpuid_t cpu);
int SchedQueueRemoveTask(sched_unit_t *su, task_t *task);

#define cur_task (SchedGetCurUnit()->cur)

#endif